//
//  Order.swift
//  CMB250716
//
//  Created by Andy Lau on 16/7/25.
//

import Foundation

// 订单状态
enum OrderStatus: String, Codable, CaseIterable {
    case pending = "等待确认"
    case confirmed = "已确认"
    case preparing = "制作中"
    case ready = "已完成"
    case completed = "已出"
    case cancelled = "已取消"
    
    var englishName: String {
        switch self {
        case .pending: return "Pending"
        case .confirmed: return "Confirmed"
        case .preparing: return "Preparing"
        case .ready: return "Ready"
        case .completed: return "Completed"
        case .cancelled: return "Cancelled"
        }
    }
    
    var displayName: String {
        self.rawValue
    }
    
    var englishDisplayName: String {
        self.englishName
    }
    
    var progressValue: Int {
        switch self {
        case .pending: return 1
        case .confirmed: return 2
        case .preparing: return 3
        case .ready: return 4
        case .completed: return 5
        case .cancelled: return 0
        }
    }
}

// 用餐方式
enum DiningType: String, Codable, CaseIterable {
    case dineIn = "堂食"
    case takeaway = "外带"
    
    var englishName: String {
        switch self {
        case .dineIn: return "Dine In"
        case .takeaway: return "Takeaway"
        }
    }
}

// 支付方式
enum PaymentMethod: String, Codable, CaseIterable {
    case creditCard = "信用卡"
    case payNow = "PayNow"
    case applePay = "Apple Pay"
    case googlePay = "Google Pay"
    
    var englishName: String {
        switch self {
        case .creditCard: return "Credit Card"
        case .payNow: return "PayNow"
        case .applePay: return "Apple Pay"
        case .googlePay: return "Google Pay"
        }
    }
}

// 订单模型
struct Order: Identifiable, Codable {
    var id = UUID()
    let orderNumber: String
    let userId: UUID?
    let tableNumber: String?
    let items: [CartItem]
    let subtotal: Double
    let tax: Double
    let discount: Double
    let couponDiscount: Double
    let pointsDiscount: Double
    let total: Double
    let pointsEarned: Int
    let pointsUsed: Int
    var status: OrderStatus
    let diningType: DiningType
    let paymentMethod: PaymentMethod
    let orderDate: Date
    var completedDate: Date?
    let specialInstructions: String?
    
    // 后端数据库ID，用于API调用
    var backendId: Int?
    let appliedCoupon: Coupon?
    var pointsAwarded: Bool = false  // 新增标志，防止重复发放积分
    
    // 预订相关属性
    let isReservation: Bool // 是否为预订订单
    let reservationTime: Date? // 预订时间（仅预订订单有效）
    let reservationPartySize: Int? // 预订人数
    let reservationSeatingType: ReservationConfig.SeatingType? // 座位类型
    let reservationSpecialRequests: String? // 特殊要求 
    init(userId: UUID?, tableNumber: String?, items: [CartItem], diningType: DiningType, paymentMethod: PaymentMethod, specialInstructions: String? = nil, appliedCoupon: Coupon? = nil, pointsUsed: Int = 0, userMembershipLevel: MembershipLevel = .lv1, isReservation: Bool = false, reservationTime: Date? = nil, reservationPartySize: Int? = nil, reservationSeatingType: ReservationConfig.SeatingType? = nil, reservationSpecialRequests: String? = nil) {
        // 判断是否为游客（userId为nil表示游客）
        let isGuest = (userId == nil)
        self.orderNumber = Order.generateOrderNumber(diningType: diningType, isGuest: isGuest, isReservation: isReservation)
        self.userId = userId
        self.tableNumber = tableNumber
        self.items = items
        self.diningType = diningType
        self.paymentMethod = paymentMethod
        self.specialInstructions = specialInstructions
        self.pointsUsed = pointsUsed
        
        // 检查是否只有Cash Voucher
        let hasCashVoucher = items.contains { $0.menuItem.name == AppConfig.Cart.voucherPackageName }
        let hasOnlyCashVoucher = hasCashVoucher && items.allSatisfy { $0.menuItem.name == AppConfig.Cart.voucherPackageName }
        
        // 获取非Cash Voucher商品的总价
        let nonCashVoucherTotal = items.filter { $0.menuItem.name != AppConfig.Cart.voucherPackageName }.reduce(0) { $0 + $1.totalPrice }
        
        // 获取Cash Voucher商品的总价
        let cashVoucherTotal = items.filter { $0.menuItem.name == AppConfig.Cart.voucherPackageName }.reduce(0) { $0 + $1.totalPrice }
        
        // 计算税前小计（从含税价格倒算）
        if hasOnlyCashVoucher {
            // 如果只有Cash Voucher，直接使用其价格（无GST）
            self.subtotal = cashVoucherTotal
        } else if hasCashVoucher {
            // 如果有Cash Voucher和其他商品，只对非Cash Voucher商品计算GST
            self.subtotal = (nonCashVoucherTotal / 1.09) + cashVoucherTotal
        } else {
            // 正常情况：从含税价格倒算税前价格
            let totalPrice = items.reduce(0) { $0 + $1.totalPrice }
            self.subtotal = totalPrice / 1.09
        }
        
        // 计算折扣（基于税前价格）
        var couponDiscountAmount = 0.0
        if let coupon = appliedCoupon, !hasOnlyCashVoucher {
            // 优惠券折扣基于税前价格计算
            let discountableAmount = hasOnlyCashVoucher ? 0 : (hasCashVoucher ? (nonCashVoucherTotal / 1.09) : self.subtotal)
            couponDiscountAmount = coupon.calculateDiscount(for: discountableAmount)
        }
        
        // 根据会员级别计算积分抵扣金额
        let pointsDiscountAmount: Double
        if pointsUsed >= userMembershipLevel.minimumPointsForDiscount && !hasOnlyCashVoucher {
            let discountGroups = pointsUsed / userMembershipLevel.pointsPerDiscount
            pointsDiscountAmount = Double(discountGroups) * 5.0 // 每组抵扣5元
        } else {
            pointsDiscountAmount = 0.0
        }
        
        self.discount = couponDiscountAmount + pointsDiscountAmount
        self.couponDiscount = couponDiscountAmount
        self.pointsDiscount = pointsDiscountAmount
        
        // 计算折扣后的税前小计
        let subtotalAfterDiscount = max(0, self.subtotal - self.discount)
        
        // 计算GST和总价
        if hasOnlyCashVoucher {
            // Cash Voucher无GST
            self.tax = 0.0
            self.total = subtotalAfterDiscount
            self.pointsEarned = 0 // Cash Voucher不计算积分
        } else {
            // 计算GST（基于折扣后的税前价格）
            self.tax = subtotalAfterDiscount * 0.09
            self.total = subtotalAfterDiscount + self.tax
            
            // 计算积分
            if hasCashVoucher {
                // 如果有Cash Voucher，只对非Cash Voucher项目计算积分
                let nonCashVoucherSubtotal = nonCashVoucherTotal / 1.09
                let discountedNonCashVoucherSubtotal = max(0, nonCashVoucherSubtotal - self.discount)
                let nonCashVoucherTotalWithTax = discountedNonCashVoucherSubtotal + (discountedNonCashVoucherSubtotal * 0.09)
                self.pointsEarned = Int(nonCashVoucherTotalWithTax + cashVoucherTotal)
            } else {
                self.pointsEarned = Int(self.total) // 每消费S$1积1分
            }
        }
        
        self.status = .pending
        self.orderDate = Date()
        self.completedDate = nil
        self.appliedCoupon = appliedCoupon
        self.isReservation = isReservation
        self.reservationTime = reservationTime
        self.reservationPartySize = reservationPartySize
        self.reservationSeatingType = reservationSeatingType
        self.reservationSpecialRequests = reservationSpecialRequests
    }
    
    // 统一的订单类型显示名称（含预订类型），按语言返回
    func displayOrderType(language: String = "zh") -> String {
        if isReservation {
            if language == "zh" {
                return diningType == .dineIn ? "预订-堂食" : "预订-外带"
            } else {
                return diningType == .dineIn ? "Reservation - Dine-in" : "Reservation - Takeaway"
            }
        } else {
            if language == "zh" {
                return diningType.rawValue
            } else {
                return diningType.englishName
            }
        }
    }
    
    // 新增：提供在未创建订单时的统一用餐类型显示（如支付页）
    static func displayOrderType(diningType: DiningType, isReservation: Bool, language: String = "zh") -> String {
        if isReservation {
            if language == "zh" {
                return diningType == .dineIn ? "预订-堂食" : "预订-外带"
            } else {
                return diningType == .dineIn ? "Reservation - Dine-in" : "Reservation - Takeaway"
            }
        } else {
            if language == "zh" {
                return diningType.rawValue
            } else {
                return diningType.englishName
            }
        }
    }
    
    static func generateOrderNumber(diningType: DiningType = .dineIn, isGuest: Bool = true, isReservation: Bool = false) -> String {
        // 新的编号规则：
        // 前缀字母规则：
        // - N = Now（即时订单）
        // - R = Reservation（预订订单）
        // - D = Dine-in（堂食）
        // - T = Take-away（外带）
        // - G = Guest（非会员用户，可选前缀）
        
        // 构建前缀
        let guestPrefix = isGuest ? "G" : ""  // 非会员用户添加G前缀
        let timePrefix = isReservation ? "R" : "N"  // 预订R，即时N
        let typePrefix = (diningType == .takeaway) ? "T" : "D"  // 外带T，堂食D
        
        let prefix = guestPrefix + timePrefix + typePrefix
        
        // 获取全局计数器（所有订单类型共享同一个序号）
        let counterKey = "\(AppConfig.StorageKeys.nextOrderNumber)_global"
        let defaults = UserDefaults.standard
        var nextNumber = defaults.integer(forKey: counterKey)
        if nextNumber == 0 {
            nextNumber = 5168 // 从5168开始，与后端保持一致
        }
        
        let orderNumber = "\(prefix)-\(nextNumber)"
        defaults.set(nextNumber + 1, forKey: counterKey)
        return orderNumber
    }
    
    mutating func updateStatus(_ newStatus: OrderStatus) {
        self.status = newStatus
        if newStatus == .completed || newStatus == .ready {
            self.completedDate = Date()
        }
    }
}

// 优惠券模型
struct Coupon: Identifiable, Codable, Equatable {
    var id = UUID()
    let code: String
    let title: String
    let englishTitle: String
    let description: String
    let englishDescription: String
    let discountType: DiscountType
    let discountValue: Double
    let minimumSpend: Double
    let maximumDiscount: Double?
    let validFrom: Date
    let validUntil: Date
    let isActive: Bool
    let usageLimit: Int?
    var usageCount: Int
    
    // 新增属性
    let excludeAlcoholicBeverages: Bool // 是否排除酒水
    let applicableTimeSlots: [TimeSlot]? // 适用时间段
    let usageFrequency: UsageFrequency? // 使用频率限制
    let relativeDuration: RelativeDuration? // 相对有效期
    let reminderDays: Int // 到期提醒天数
    
    // 激活条件相关属性
    let activationConditions: String? // 中文激活条件描述
    let englishActivationConditions: String? // 英文激活条件描述
    let requiresLogin: Bool // 是否需要登录
    let requiresMembershipLevel: String? // 需要的会员等级
    
    enum DiscountType: String, Codable {
        case percentage = "百分比"
        case fixedAmount = "固定金额"
        
        var englishName: String {
            switch self {
            case .percentage: return "Percentage"
            case .fixedAmount: return "Fixed Amount"
            }
        }
    }
    
    func calculateDiscount(for amount: Double) -> Double {
        guard amount >= minimumSpend else { return 0 }
        
        var discount: Double
        switch discountType {
        case .percentage:
            discount = amount * (discountValue / 100)
        case .fixedAmount:
            discount = discountValue
        }
        
        if let maxDiscount = maximumDiscount {
            discount = min(discount, maxDiscount)
        }
        
        return discount
    }
    
    func calculateDiscount(for items: [CartItem]) -> Double {
        guard isValid else { return 0 }
        
        // 计算符合条件的商品总价
        let eligibleSubtotal = items.reduce(0) { total, item in
            // 如果排除酒水且当前商品是酒水，则跳过
            if excludeAlcoholicBeverages && item.menuItem.category == .drinks {
                return total
            }
            return total + item.totalPrice
        }
        
        guard eligibleSubtotal >= minimumSpend else { return 0 }
        
        switch discountType {
        case .percentage:
            let discount = eligibleSubtotal * (discountValue / 100)
            return min(discount, maximumDiscount ?? discount)
        case .fixedAmount:
            return min(discountValue, eligibleSubtotal)
        }
    }
    
    // 检查当前时间是否在适用时间段内
    func isApplicableAtCurrentTime() -> Bool {
        guard let timeSlots = applicableTimeSlots else { return true }
        
        let now = Date()
        let calendar = Calendar.current
        let weekday = calendar.component(.weekday, from: now)
        let hour = calendar.component(.hour, from: now)
        let minute = calendar.component(.minute, from: now)
        let currentTime = hour * 60 + minute // 转换为分钟
        
        return timeSlots.contains { timeSlot in
            timeSlot.weekdays.contains(weekday) &&
            currentTime >= timeSlot.startTime &&
            currentTime <= timeSlot.endTime
        }
    }
    
    // 检查使用频率限制
    func canUseBasedOnFrequency(lastUsedDate: Date?) -> Bool {
        guard let frequency = usageFrequency else { return true }
        
        // 如果是一次性使用，检查是否已经使用过
        if frequency == .once {
            return lastUsedDate == nil
        }
        
        guard let lastUsed = lastUsedDate else { return true }
        
        let calendar = Calendar.current
        let now = Date()
        
        switch frequency {
        case .once:
            return false // 已经使用过了
        case .daily:
            return !calendar.isDate(lastUsed, inSameDayAs: now)
        case .weekly:
            guard let currentWeekInterval = calendar.dateInterval(of: .weekOfYear, for: now) else {
                return true
            }
            return !currentWeekInterval.contains(lastUsed)
        case .monthly:
            let month = calendar.component(.month, from: now)
            let lastUsedMonth = calendar.component(.month, from: lastUsed)
            let year = calendar.component(.year, from: now)
            let lastUsedYear = calendar.component(.year, from: lastUsed)
            return !(month == lastUsedMonth && year == lastUsedYear)
        case .yearly:
            let year = calendar.component(.year, from: now)
            let lastUsedYear = calendar.component(.year, from: lastUsed)
            return year != lastUsedYear
        case .perOrder:
            return true // 每单限用一次，在购物车中处理限制逻辑
        }
    }
    
    // 计算相对有效期
    func calculateValidUntil(from startDate: Date) -> Date {
        guard let duration = relativeDuration else { return validUntil }
        
        let calendar = Calendar.current
        switch duration {
        case .days(let days):
            return calendar.date(byAdding: .day, value: days, to: startDate) ?? validUntil
        case .weeks(let weeks):
            return calendar.date(byAdding: .weekOfYear, value: weeks, to: startDate) ?? validUntil
        case .months(let months):
            return calendar.date(byAdding: .month, value: months, to: startDate) ?? validUntil
        case .years(let years):
            return calendar.date(byAdding: .year, value: years, to: startDate) ?? validUntil
        }
    }
    
    // 检查是否需要发送到期提醒
    func shouldSendExpiryReminder() -> Bool {
        let calendar = Calendar.current
        let now = Date()
        let daysUntilExpiry = calendar.dateComponents([.day], from: now, to: validUntil).day ?? 0
        return daysUntilExpiry <= reminderDays && daysUntilExpiry > 0
    }
    
    var isValid: Bool {
        let now = Date()
        return isActive && now >= validFrom && now <= validUntil
    }
}

// 新增枚举类型
enum UsageFrequency: Codable, Equatable {
    case once
    case daily
    case weekly
    case monthly
    case yearly
    case perOrder // 每单限用一次
}

enum RelativeDuration: Codable, Equatable {
    case days(Int)
    case weeks(Int)
    case months(Int)
    case years(Int)
}

struct TimeSlot: Codable, Equatable {
    let weekdays: [Int] // 1=周日, 2=周一, ..., 7=周六
    let startTime: Int // 分钟数，如 11:00 = 660
    let endTime: Int // 分钟数，如 19:00 = 1140
}